package other.xsy.passlys.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.data.model.Opportunity;
import com.rkhd.platform.sdk.exception.ApiEntityServiceException;
import com.rkhd.platform.sdk.exception.CacheException;
import com.rkhd.platform.sdk.exception.CustomConfigException;
import com.rkhd.platform.sdk.exception.XsyHttpException;
import com.rkhd.platform.sdk.http.CommonData;
import com.rkhd.platform.sdk.http.CommonHttpClient;
import com.rkhd.platform.sdk.http.CommonResponse;
import com.rkhd.platform.sdk.http.HttpResult;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.service.CacheService;
import com.rkhd.platform.sdk.service.CustomConfigService;
import com.rkhd.platform.sdk.service.XObjectService;
import org.apache.commons.lang.StringUtils;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**功能描述：调用PMS接口/获取token工具类
 * @ClassName: PromotionApiUtil
 * @Description: 调用PMS接口/获取token工具类
 * @author 黄梓豪
 * @date 2024年03月15日
 */
public class PromotionApiUtil {
    public static String BASE_URL = "https://pms.tcl.com"; // 正式地址 https://pms.tcl.com
    // todo 发布需要使用正式环境
    //public static String BASE_URL = "http://kong.poros-platform.10.74.162.19.sit.docker.tcl.com"; // 测试环境(需要使用VPN)
    public static String SALE_OPPORTUNITIES_URL = BASE_URL + "/api/pms-service/sfdc/businessOpportunity"; // 销售机会同步接口
    public static String ACCOUNT_URL = BASE_URL + "/api/pms-service/sfdc/customer";    //客户同步接口
    public static String TOKEN_URL = BASE_URL + "/api/poros-authcenter/oauth/token?grant_type=username&username="; // 获取PMS系统token接口
    public static String ESTIMATE_URL = BASE_URL + "/api/pms-service/preEstimate/getReviewByOpportunityId/"; // 获取机会概算信息
    public static String BUDGET_URL = BASE_URL + "/api/pms-service/versionPlan/getProjectBudgetVo/"; // 获取机会预算信息
    public static String INSERT_ORDER_URL = BASE_URL + "/api/pms-service/order/insert"; // 插入订单信息
    private static final Logger logger = LoggerFactory.getLogger();
    public static final CommonHttpClient CLIENT = CommonHttpClient.instance();
    private static final CacheService cacheService = CacheService.instance();
    private static final String TOKEN_KEY = "PMS_TOKEN";

    /**
     * 根据业务机会获取PMS的预算或者概算数据
     * @param opportunity
     * @return
     * @throws ApiEntityServiceException
     */
    public static JSONObject getPmsOrderDetail(Opportunity opportunity) throws CustomConfigException, CacheException, XsyHttpException {
        logger.info("根据业务机会获取PMS的预算或者概算数据");
        Long opportunityId = opportunity.getId();
        String sfId = opportunity.getSF_ID__c();

        Integer projectPhase = opportunity.getProjectPhase__c();
        // 判断当前 项目阶段 1:售前 (查询概算)  2: 交付   (查询预算)
        JSONObject budgetData = new JSONObject();
        if (projectPhase != null && projectPhase > 1) {
            logger.info("查询预算数据 ========= ");
            String optId = StringUtils.isNotBlank(sfId) ? sfId : opportunityId.toString();
            budgetData = PromotionApiUtil.sendPmsGet(PromotionApiUtil.BUDGET_URL + optId);

            // 如果 sfId 查询为空，则用 opportunityId 再次查询
            if (budgetData.getJSONObject("data") == null && StringUtils.isNotBlank(sfId)) {
                budgetData = PromotionApiUtil.sendPmsGet(PromotionApiUtil.BUDGET_URL + opportunityId);
            }
        }

        // 没有预算查询概算
        JSONObject tempData = budgetData.getJSONObject("data");
        if (tempData == null) {
            logger.info("查询概算数据 ========= ");
            String opportunityIds = opportunityId.toString();
            if (StringUtils.isNotBlank(sfId)) {
                opportunityIds += "," + sfId;
            }
            budgetData = PromotionApiUtil.getEstimateData(opportunityIds);
        }

        JSONObject pmsData = budgetData.getJSONObject("data");
        logger.info("返回数据 ========= "+ pmsData);
        return pmsData;
    }


    /**
     * 根据机会点获取概算信息：需要兼容一个业绩机会在PMS推送了两条数据的问题（SFid & crmid）
     * @param opportunityIds
     * @return
     * @throws CustomConfigException
     * @throws XsyHttpException
     */
    public static JSONObject getEstimateData(String opportunityIds) throws CustomConfigException, XsyHttpException, CacheException {

        CommonData build = CommonData.newBuilder().callString(ESTIMATE_URL + opportunityIds)
                .callType("GET")
                .header("Authorization", "bearer " + getToken())
                .build();
        HttpResult execute = CLIENT.execute(build);
        String result = execute.getResult();
        JSONObject jsonObject = JSONObject.parseObject(result);
        // 判断是否token过期
        if (jsonObject.getInteger("code") == 401) {
            // 重新发起请求
            logger.error("PMS token过期，重新发起请求");
            cacheService.delete(TOKEN_KEY);
            return getEstimateData(opportunityIds);
        }

        // 获取值
        Map<String, Object> map = jsonObject.getJSONObject("data");
        logger.info("estimateData ==> " + map);
        if (map != null && map.size() > 0) {
            String firstKey = map.keySet().iterator().next();
            jsonObject.put("data", map.get(firstKey));
        }
        return jsonObject;
    }


    public static JSONObject sendPmsPost(Object object, String url) throws CustomConfigException, XsyHttpException, CacheException {
        CommonData build = CommonData.newBuilder().callString(url)
                .callType("POST")
                .header("Authorization", "bearer " + getToken())
                .body(JSON.toJSONString(object))
                .formType("application/json")
                .build();
        HttpResult execute = CLIENT.execute(build);
        String result = execute.getResult();
        System.out.println("result = " + result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        // 判断是否token过期
        if (jsonObject.getInteger("code") == 401) {
            // 重新发起请求
            logger.error("PMS token过期，重新发起请求");
            cacheService.delete(TOKEN_KEY);
            return sendPmsPost(object, url);
        }
        return jsonObject;
    }

    public static JSONObject sendPmsGet(String url) throws CustomConfigException, XsyHttpException, CacheException {
        logger.info("sendPmsGet = " + url);
        CommonData build = CommonData.newBuilder().callString(url)
                .callType("GET")
                .header("Authorization", "bearer " + getToken())
                .build();
        HttpResult execute = CLIENT.execute(build);
        String result = execute.getResult();
        System.out.println("result = " + result);
        JSONObject jsonObject = JSONObject.parseObject(result);

        // 判断是否token过期
        if (jsonObject.getInteger("code") == 401) {
            // 重新发起请求
            logger.error("PMS token过期，重新发起请求");
            cacheService.delete(TOKEN_KEY);
            return sendPmsGet(url);
        }
        return jsonObject;
    }


    /**
     * 同步机会信息到PMS
     * @param jsonArray
     * @param url
     * @return
     */
    public static JSONObject sendToPms(JSONArray jsonArray,String url) throws CustomConfigException, CacheException, XsyHttpException {
        CommonData build = CommonData.newBuilder().callString(url)
                .callType("POST")
                .header("Authorization", "bearer " + getToken())
                .body(jsonArray.toJSONString())
                .formType("application/json")
                .build();
        System.out.println("打印json"+jsonArray.toJSONString());
        HttpResult execute = CLIENT.execute(build);
        String result = execute.getResult();
        logger.info("同步结果" + result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        // 判断是否token过期
        if (jsonObject.getInteger("code") == 401) {
            // 重新发起请求
            logger.error("PMS token过期，重新发起请求");
            cacheService.delete(TOKEN_KEY);
            return sendToPms(jsonArray, url);
        }
        return jsonObject;
    }

    //获取token
    public static String getToken() throws XsyHttpException, CustomConfigException, CacheException {
        // 判断缓存中是否存在
        String token = cacheService.get(TOKEN_KEY);
        if (StringUtils.isNotBlank(token)) {
            logger.info("获取缓存token");
            return token;
        }

        CustomConfigService config = CustomConfigService.instance();
        Map<String, String> pmsConfig = config.getConfigSet("pms");
        if (pmsConfig == null) {
            pmsConfig = new HashMap<>();
            pmsConfig.put("clientid", "pmstest");
            pmsConfig.put("client_secret", "pmstest");
            pmsConfig.put("username", "pmstest");
        }
        String clientId = pmsConfig.get("clientid");
        String clientSecret = pmsConfig.get("client_secret");
        String userName = pmsConfig.get("username");
        String originalString = clientId + ":" + clientSecret;
        String encodedString = Base64.getEncoder().encodeToString(originalString.getBytes());
        CommonData build = CommonData.newBuilder().callString(TOKEN_URL + userName)
                .callType("POST")
                .header("Cache-Control", "no-cache")
                .header("Authorization", "Basic " + encodedString)
                .build();
        CommonResponse<JSONObject> execute = CLIENT.execute(build, JSONObject::parseObject);
        logger.info("请求结果：" + execute.getData());

        JSONObject data = execute.getData().getJSONObject("data");
        String accessToken = data.getString("accessToken");
        logger.info("pms token: " + accessToken);
        // 设置缓存值
        cacheService.set(TOKEN_KEY, accessToken);
        return accessToken;
    }

    public static void main(String[] args) throws XsyHttpException, CustomConfigException, CacheException {
        new PromotionApiUtil().getToken();
    }

}
